import re
import socket


class WSGIServer(object):

    def __init__(self, root):
        """初始化"""
        # html文件路径
        self.root = root
        """作为程序的主控制入口"""
        # 1.创建tcp的套接字
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置端口复用  当服务器先close 即服务器端4次挥手之后资源能够立即释放，这样就保证了，下次运行程序时 可以立即绑定7788端口
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # 2.绑定端口
        self.server_socket.bind(("", 7788))
        # 3.设置监听
        self.server_socket.listen(128)

    def run(self):
        """服务开始"""
        while True:
            # 获取客户端请求
            client_socket, client_addr = self.server_socket.accept()
            # 处理客户端请求
            self.handle_client(client_socket)

    def handle_client(self, client_socket):
        """处理客户端请求"""

        # 5. 接收浏览器的请求
        request = client_socket.recv(1024).decode('utf-8')
        # print(request)

        # 请求信息分行查看
        request_lines = request.splitlines()
        for i, line in enumerate(request_lines):
            print(i, line)

        # GET /index.html HTTP/1.1  正则匹配
        ret = re.match(r"([^/]*)([^ ]*)", request_lines[0])
        if ret:
            print("正则处理的数据：", ret.group(1))
            print("正则处理的数据：", ret.group(2))
            # 提取需要的文件名(包含路径)  这里是/index.html
            file_name = ret.group(2)
            # 不写index.html 也是主页
            if file_name == "/":
                file_name = "/index.html"

            # "./html/index.html"
            try:
                with open(self.root + file_name, "rb") as f:
                    # 读取文件内容
                    content = (200, f.read())  # 200 表示：http状态码
            except Exception as ret:
                content = (404, "404, 找不到您要的页面...")  # 404 表示：http状态码
        else:
            content = (500, "500, 系统异常...")  # 500 表示：http状态码

        # 组织相应 头信息(header)
        response_headers = "HTTP/1.1 %s OK\r\n" % content[0]  # 提取上述处理时的状态码
        response_headers += "Content-Type: text/html;charset=utf-8\r\n"
        response_headers += "\r\n"  # 用一个空的行与body进行隔开
        # 组织 内容(body)
        response_body = content[1].encode("utf-8")
        # 因为从文件读取出来的数据是二进制，而header是字符串，因此不能直接相加，需要分开发送
        # 先发送header
        client_socket.send(response_headers.encode("utf-8"))
        # 再发送文件的数据(body)
        client_socket.send(response_body)
        # 关闭客户端套接字
        client_socket.close()


def main():
    http_server = WSGIServer("./html")
    # 服务运行
    http_server.run()


if __name__ == "__main__":
    main()
